﻿#include <stdio.h>
#include <pcap.h>
#include<time.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<errno.h>
#include<string.h>
#include <net/if.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <netinet/in.h>


//#include <net/netfilter/nf_conntrack.h>
//#include <net/netfilter/nf_conntrack_ecache.h>
//#include <linux/netfilter/x_tables.h>
//#include <linux/netfilter/xt_connmark.h>
//#include <linux/init.h>
//#include <linux/netfilter_bridge.h>
//#include <linux/module.h>
//#include <linux/netfilter.h>
//#include <linux/socket.h>
//#include <linux/netfilter_ipv4.h>
//#include <linux/skbuff.h>
//#include <linux/netdevice.h>
//#include <linux/inet.h>
//#include <net/ip.h>
//#include <net/tcp.h>
//#include <linux/stddef.h>
//#include <linux/delay.h>
//#include <linux/jiffies.h>
//#include  <linux/list.h>



typedef struct eth_hdr
{
	u_char dst_mac[6];
	u_char src_mac[6];
	u_short eth_type;
}eth_hdr;
eth_hdr *ethernet;

typedef struct ip_hdr
{
	int version : 4;
	int header_len : 4;
	u_char tos : 8;
	int total_len : 16;
	int ident : 16;
	int flags : 16;
	u_char ttl : 8;
	u_char protocol : 8;
	int checksum : 16;
	u_char sourceIP[4];
	u_char destIP[4];
}ip_hdr;
ip_hdr *ip;

typedef struct tcp_hdr
{
	u_short sport;
	u_short dport;
	u_int seq;
	u_int ack;
	u_char head_len;
	u_char flags;
	u_short wind_size;
	u_short check_sum;
	u_short urg_ptr;
}tcp_hdr;
tcp_hdr *tcp;

typedef struct udp_hdr
{
	u_short sport;
	u_short dport;
	u_short tot_len;
	u_short check_sum;
}udp_hdr;
udp_hdr *udp;

typedef struct arppkt
{
	unsigned short hdtyp;//硬件类型
	unsigned short protyp;//协议类型
	unsigned char hdsize;//硬件地址长度
	unsigned char prosize;//协议地址长度
	unsigned short op;//（操作类型）操作值:ARP/RARP
	u_char smac[6];//源MAC地址
	u_char sip[4];//源IP地址
	u_char dmac[6];//目的MAC地址
	u_char dip[4];//目的IP地址
}arpp;

typedef struct pcapCallBakArg
{
	pcap_t *pcap_handle;
	pcap_dumper_t* fileHandle;
	char devName[20];
}pcapCallBakArg;

//pcap_t *pcap_handle = NULL;

char *format_mac_by_flag(unsigned char *mac, char *flag, char *buffer)
{
	//char buffer[64] = { 0 };
	int len = 64;

	snprintf(buffer, len - 1, "%02x%s%02x%s%02x%s%02x%s%02x%s%02x", (unsigned char)mac[0], flag, (unsigned char)mac[1], flag, (unsigned char)mac[2], flag, (unsigned char)mac[3], flag, (unsigned char)mac[4], flag, (unsigned char)mac[5]);
	//printf("MAC: %s \n", buffer);
	return buffer;
}

int get_local_mac_and_ip(char *pDeviceName, char *pOutMac, struct in_addr *ip_addr)
{
	struct ifreq Ifreq;
	int   nSock = 0, i = 0, mac_len = 6, ip_len = 4;

	if ((nSock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
	{
		printf("Create socket failed , please check\n");
		return   -1;
	}

	strcpy(Ifreq.ifr_name, pDeviceName);
	if ((i = ioctl(nSock, SIOCGIFHWADDR, &Ifreq)) < 0)
	{
		printf("I=%d\n", i);
		printf("Ioctl failed, please check \n");
		printf("Get local mac address failed \n");
		return -1;
	}
	memcpy(pOutMac, Ifreq.ifr_hwaddr.sa_data, mac_len);

	if (ioctl(nSock, SIOCGIFADDR, &Ifreq) < 0)
	{
		printf("Create socket failed , please check\n");
		printf("Get local ip address failed \n");
		return   -1;
	}

	memcpy(ip_addr, &((struct sockaddr_in *)&Ifreq.ifr_addr)->sin_addr, ip_len);

	close(nSock);
	return 0;
}


void pcap_callback(unsigned char* arg, const struct pcap_pkthdr *packet_header, const unsigned char *packet_content)
{
	static int id = 1;
	printf("id=%d\n", id++);

	pcap_dump((unsigned char *)((pcapCallBakArg*)arg)->fileHandle, packet_header, packet_content);

	printf("Packet length : %d\n", packet_header->len);
	printf("Number of bytes : %d\n", packet_header->caplen);
	printf("Received time : %s\n", ctime((const time_t*)&packet_header->ts.tv_sec));
	int i;
	for (i = 0; i < packet_header->caplen; i++) 
	{
		printf(" %02x", packet_content[i]);
		if ((i + 1) % 16 == 0) 
		{
			printf("\n");
		}
	}
	printf("\n\n");

	u_int eth_len = sizeof(struct eth_hdr);
	u_int ip_len = sizeof(struct ip_hdr);
	u_int tcp_len = sizeof(struct tcp_hdr);
	u_int udp_len = sizeof(struct udp_hdr);

	printf("analyse information:\n\n");

	printf("ethernet header information:\n");
	ethernet = (eth_hdr *)packet_content;
	printf("src_mac : %02x-%02x-%02x-%02x-%02x-%02x\n", ethernet->src_mac[0], ethernet->src_mac[1], ethernet->src_mac[2], ethernet->src_mac[3], ethernet->src_mac[4], ethernet->src_mac[5]);
	printf("dst_mac : %02x-%02x-%02x-%02x-%02x-%02x\n", ethernet->dst_mac[0], ethernet->dst_mac[1], ethernet->dst_mac[2], ethernet->dst_mac[3], ethernet->dst_mac[4], ethernet->dst_mac[5]);
	printf("ethernet type : %u\n", ethernet->eth_type);
	printf("ethernet type : %x\n", ntohs(ethernet->eth_type));


	//获取本机的ip和mac
	unsigned char mac[32] = { 0 };
	struct in_addr ip_addr;
	char str_mac[64] = { 0 };

	char local_ip[32];
	char local_mac[32];

	get_local_mac_and_ip(((pcapCallBakArg*)arg)->devName, mac, &ip_addr);
	snprintf(local_ip, sizeof(local_ip) - 1, "%s", inet_ntoa(ip_addr));
	snprintf(local_mac, sizeof(local_ip) - 1, "%s", format_mac_by_flag(mac, "-", str_mac));
	printf("local_ip = %s  local_mac = %s \n", local_ip, local_mac);


	if (ntohs(ethernet->eth_type) == 0x0800) 
	{
		printf("IPV4 is used\n");
		printf("IPV4 header information:\n");
		ip = (ip_hdr*)(packet_content + eth_len);
		printf("source ip : %d.%d.%d.%d\n", ip->sourceIP[0], ip->sourceIP[1], ip->sourceIP[2], ip->sourceIP[3]);
		printf("dest ip : %d.%d.%d.%d\n", ip->destIP[0], ip->destIP[1], ip->destIP[2], ip->destIP[3]);
		if (ip->protocol == 6)
		{
			printf("tcp is used:\n");
			tcp = (tcp_hdr*)(packet_content + eth_len + ip_len);
			printf("tcp source port : %u\n", tcp->sport);
			printf("tcp dest port : %u\n", tcp->dport);
		}
		else if (ip->protocol == 17) {
			printf("udp is used:\n");
			udp = (udp_hdr*)(packet_content + eth_len + ip_len);
			printf("udp source port : %u\n", udp->sport);
			printf("udp dest port : %u\n", udp->dport);
		}
		else 
		{
			printf("other transport protocol is used\n");
		}
	}
	else if (ntohs(ethernet->eth_type) == 0x0806)
	{
		printf("line:%d________________%02x\n", __LINE__, packet_content[12]);
		printf("line:%d________________%02x\n", __LINE__, packet_content[13]);

		printf("ARP protocol!\n");

         arpp* arph = (arpp *)(packet_content + 14);
         //输出源IP
         printf("源IP：");
		 char recSrcIp[30] = { 0 };
         for (i = 0; i < 3; i++)
         {
             //printf("%d.", arph->sip[i]);
			 sprintf(recSrcIp, "%s%d.", recSrcIp, arph->sip[i]);
         }
		 sprintf(recSrcIp, "%s%d", recSrcIp, arph->sip[3]);
		 //printf("%d\t", arph->sip[3]);
		 printf("%s\t", recSrcIp);

         //输出目的IP
         printf("目的IP：");
		 char recDesIp[30] = { 0 };
         for (i = 0; i < 3; i++)
         {
             //printf("%d.", arph->dip[i]);
			 sprintf(recDesIp, "%s%d.", recDesIp, arph->dip[i]);
         }
         //printf("%d\t", arph->dip[3]);
		 sprintf(recDesIp, "%s%d", recDesIp, arph->dip[3]);
		 printf("%s\t", recDesIp);

         //输出源mac
		 printf("源mac：");
		 char recSrcMac[30] = { 0 };
         for (i = 0; i < 5; i++)
         {
             //printf("%x-", arph->smac[i]);
			 sprintf(recSrcMac, "%s%x-", recSrcMac, arph->smac[i]);
         }
         //printf("%x\t", arph->smac[5]);
		 sprintf(recSrcMac, "%s%x\t", recSrcMac, arph->sip[3]);
		 printf("%s\t", recSrcMac);

         //输出目的mac
         printf("目的mac：");
		 char recDesMac[30] = { 0 };
         for (i = 0; i < 5; i++)
         {
             //printf("%x-", *(packet_content + i));
			 sprintf(recDesMac, "%s%x-", recDesMac, *(packet_content + i));
         }
         //printf("%x\t", *(packet_content + 5));
		 sprintf(recDesMac, "%s%x\t", recDesMac, *(packet_content + 5));
		 printf("%s\t", recDesMac);

         //输出操作类型
         printf("操作类型（ARP/RARP）：");
         if (arph->op == 256)
         {
             printf("ARP\t");
         }
         else
         {
             printf("RARP\t");
         }

         printf("\n");
         printf("-----------------收到arp包并解析完毕---------------------\n");

		 //模拟构造arp的回复包
		 if (1)//
		 {
			 printf("-----------------构造arp包并解析发送---------------------\n");
			 int k = 0;
			 int temp[3];
			 u_char packet[100] = {0};
			 memset(packet, 0, 100);
			 char desmac[30];
			 strcpy(desmac, recSrcMac);
			//目的MAC地址
			for (i = 0; i < 18; i = i + 3)
			{
				temp[0] = (int)desmac[i];
				temp[1] = (int)desmac[i + 1];
				if (temp[0] > 96)                   
					temp[0] = temp[0] - 87;  //当输入mac为小写字母时字符转换为16进制
				else if (temp[0] > 64)
					temp[0] = temp[0] - 55;  //当输入mac为大写字母时字符转换为16进制
				else
					temp[0] = temp[0] - 48; //当输入mac为数字时字符转换为16进制
				
				
				if (temp[1] > 96)
					temp[1] = temp[1] - 87; //当输入mac为小写字母时字符转换为16进制
				else if (temp[1] > 64)
					temp[1] = temp[1] - 55; //当输入mac为大写字母时字符转换为16进制
				else
					temp[1] = temp[1] - 48; //当输入mac为数字时字符转换为16进制

				packet[k] = packet[32 + k] = temp[0] * 16 + temp[1];//?转成十进制放入packet
				k++;
			}

			//应答ARP请求时源MAC
			char srcmac[30];
			strcpy(srcmac, local_mac);
			k = 0;
			//源MAC地址
			for (i = 0; i < 18; i = i + 3)
			{
				temp[0] = (int)srcmac[i];
				temp[1] = (int)srcmac[i + 1];
				if (temp[0] > 96)
					temp[0] = temp[0] - 87;  //当输入mac为小写字母时字符转换为16进制
				else if (temp[0] > 64)
					temp[0] = temp[0] - 55;  //当输入mac为大写字母时字符转换为16进制
				else
					temp[0] = temp[0] - 48; //当输入mac为数字时字符转换为16进制


				if (temp[1] > 96)
					temp[1] = temp[1] - 87; //当输入mac为小写字母时字符转换为16进制
				else if (temp[1] > 64)
					temp[1] = temp[1] - 55; //当输入mac为大写字母时字符转换为16进制
				else
					temp[1] = temp[1] - 48; //当输入mac为数字时字符转换为16进制

				packet[6 + k] = packet[22 + k] = temp[0] * 16 + temp[1];//?转成十进制放入packet
				k++;
			}

			//应答ARP请求时把源MAC置为0,为了方便wireshark抓包看包所写
			//for (i = 0; i < 6; i++)
			//{
			//	packet[6 + i] = packet[22 + i] = 0x00;
			//}

			char srcIp[100] = {0};
			char desIp[100] = {0};

			strcpy(srcIp, local_ip);
			strcpy(desIp, recSrcIp);
			//源IP地址
			 k = 0;
			 int j = 0;
			 temp[2] = 0;  //指向每个字节初始位置
			 for (i = 0; i < 4; i++)
			 {
				 temp[0] = 0;
				 temp[1] = 0;
				 for (j = 0; j < 4; j++)
				 {
					 if (srcIp[j + temp[2]] >= '0'&&srcIp[j + temp[2]] <= '9')
					 {
						 temp[0] = (int)srcIp[j + temp[2]] - 48;//字符1转int型数据1
						 temp[1] = temp[1] * 10 + temp[0];//字符192转换成int数据192，累乘10
						 //printf("%d %d\n",temp[0],temp[1]);
					 }
					 else
					 {
						 //当遇到点时j自加1目的是让temp[2]+j指向下一字节的第一位
						 j++;
						 break;
					 }
				 }
				 packet[28 + k] = temp[1];
				 k++;
				 temp[2] += j;
			 }

			 //目标IP地址
			 k = 0;
			 temp[2] = 0;
			 for (i = 0; i < 4; i++)
			 {
				 temp[0] = 0;
				 temp[1] = 0;
				 for (j = 0; j < 4; j++)
				 {
					 if (desIp[j + temp[2]] >= '0'&&desIp[j + temp[2]] <= '9')
					 {
						 temp[0] = (int)desIp[j + temp[2]] - 48;
						 temp[1] = temp[1] * 10 + temp[0];
						 //printf("%d %d\n",temp[0],temp[1]);
					 }
					 else
					 {
						 j++;
						 break;
					 }
				 }
				 packet[38 + k] = temp[1];
				 k++;
				 temp[2] += j;
			 }

			 //ARP首部
			 packet[12] = 0x08;//12、13位为帧类型
			 packet[13] = 0x06;
			 packet[14] = 0x00;//14、15位为硬件类型
			 packet[15] = 0x01;
			 packet[16] = 0x08;//16、17位为协议类型
			 packet[17] = 0x00;
			 packet[18] = 0x06;//硬件地址长度
			 packet[19] = 0x04;//协议地址长度
			 packet[20] = 0x00;//op
			 packet[21] = 0x02;//op(1为请求2为应答)


			 /* 填充发送包的剩余部分 */
			 for (i = 0; i < 18; i++)
			 {
				 packet[42 + i] = 0;
			 }

			 //这里后四个字节本应该是校验位,这里就不算了，写个日期纪念一下
			 packet[59] = 0x20;
			 packet[60] = 0x21;
			 packet[61] = 0x11;
			 packet[62] = 0x06;
			 /* 发送包 */

			 pcap_sendpacket(((pcapCallBakArg*)arg)->pcap_handle, packet, 64);
			 printf(" send Success!\n");
		 }
	}
	else if ((ntohs(ethernet->eth_type) == 0x8100))
	{
		//struct iphdr *iph;
		struct vlan_hdr *vhdr;
		unsigned short vlan_id;
		unsigned short vlan_tci;

		/*get vlan_id*/
		//vhdr = (struct vlan_hdr *)(packet_content + 12 + 2 );
		//vlan_tci = ntohs(vhdr->h_vlan_TCI);
		////vlan_id = vlan_tci & VLAN_VID_MASK;


		printf("vlan ARP protocol!\n");

		printf("line:%d________________%02x\n", __LINE__, packet_content[14]);
		printf("line:%d________________%02x\n", __LINE__, packet_content[15]);

		arpp* arph = (arpp *)(packet_content + 12 + 2 + 2 + 2);//偏移mac地址12位+802.1Q协议类型2位+vlan标签两位+arp协议标记2位
		//输出源IP
		printf("源IP：");
		char recSrcIp[30] = { 0 };
		for (i = 0; i < 3; i++)
		{
			//printf("%d.", arph->sip[i]);
			sprintf(recSrcIp, "%s%d.", recSrcIp, arph->sip[i]);
		}
		sprintf(recSrcIp, "%s%d", recSrcIp, arph->sip[3]);
		//printf("%d\t", arph->sip[3]);
		printf("%s\t", recSrcIp);

		//输出目的IP
		printf("目的IP：");
		char recDesIp[30] = { 0 };
		for (i = 0; i < 3; i++)
		{
			//printf("%d.", arph->dip[i]);
			sprintf(recDesIp, "%s%d.", recDesIp, arph->dip[i]);
		}
		//printf("%d\t", arph->dip[3]);
		sprintf(recDesIp, "%s%d", recDesIp, arph->dip[3]);
		printf("%s\t", recDesIp);

		//输出源mac
		printf("源mac：");
		char recSrcMac[30] = { 0 };
		for (i = 0; i < 5; i++)
		{
			//printf("%x-", arph->smac[i]);
			sprintf(recSrcMac, "%s%x-", recSrcMac, arph->smac[i]);
		}
		//printf("%x\t", arph->smac[5]);
		sprintf(recSrcMac, "%s%x\t", recSrcMac, arph->sip[3]);
		printf("%s\t", recSrcMac);

		//输出目的mac
		printf("目的mac：");
		char recDesMac[30] = { 0 };
		for (i = 0; i < 5; i++)
		{
			//printf("%x-", *(packet_content + i));
			sprintf(recDesMac, "%s%x-", recDesMac, *(packet_content + i));
		}
		//printf("%x\t", *(packet_content + 5));
		sprintf(recDesMac, "%s%x\t", recDesMac, *(packet_content + 5));
		printf("%s\t", recDesMac);

		//输出操作类型
		printf("操作类型（ARP/RARP）：");
		if (arph->op == 256)
		{
			printf("ARP\t");
		}
		else
		{
			printf("RARP\t");
		}

		printf("\n");
		printf("-----------------收到arp包并解析完毕---------------------\n");

		//模拟构造arp的回复包
		if (1)//
		{
			printf("-----------------构造arp包并解析发送---------------------\n");
			int k = 0;
			int temp[3];
			u_char packet[100] = {0};
			memset(packet, 0, 100);
			char desmac[30] = {0};
			strcpy(desmac, recSrcMac);
			printf("#########################desmac = %s\n", desmac);
			//目的MAC地址
			for (i = 0; i < 18; i = i + 3)
			{
				temp[0] = (int)desmac[i];
				temp[1] = (int)desmac[i + 1];
				if (temp[0] > 96)
					temp[0] = temp[0] - 87;  //当输入mac为小写字母时字符转换为16进制
				else if (temp[0] > 64)
					temp[0] = temp[0] - 55;  //当输入mac为大写字母时字符转换为16进制
				else
					temp[0] = temp[0] - 48; //当输入mac为数字时字符转换为16进制


				if (temp[1] > 96)
					temp[1] = temp[1] - 87; //当输入mac为小写字母时字符转换为16进制
				else if (temp[1] > 64)
					temp[1] = temp[1] - 55; //当输入mac为大写字母时字符转换为16进制
				else
					temp[1] = temp[1] - 48; //当输入mac为数字时字符转换为16进制

				packet[k] = packet[32 + 4 + k] = temp[0] * 16 + temp[1];//
				k++;
			}

			printf("des mac making !!!\n");
			for (i = 0; i < 64; i++)
			{
				printf(" %02x", packet[i]);
				if ((i + 1) % 16 == 0)
				{
					printf("\n");
				}
			}
			printf("\n\n");


			//应答ARP请求时源MAC
			char srcmac[30];
			strcpy(srcmac, local_mac);
			//源MAC地址
			k = 0;
			printf("#########################srcmac = %s\n", srcmac);
			for (i = 0; i < 18; i = i + 3)
			{
				temp[0] = (int)srcmac[i];
				temp[1] = (int)srcmac[i + 1];
				if (temp[0] > 96)
					temp[0] = temp[0] - 87;  //当输入mac为小写字母时字符转换为16进制
				else if (temp[0] > 64)
					temp[0] = temp[0] - 55;  //当输入mac为大写字母时字符转换为16进制
				else
					temp[0] = temp[0] - 48; //当输入mac为数字时字符转换为16进制


				if (temp[1] > 96)
					temp[1] = temp[1] - 87; //当输入mac为小写字母时字符转换为16进制
				else if (temp[1] > 64)
					temp[1] = temp[1] - 55; //当输入mac为大写字母时字符转换为16进制
				else
					temp[1] = temp[1] - 48; //当输入mac为数字时字符转换为16进制

				packet[6 + k] = packet[22 + 4 + k] = temp[0] * 16 + temp[1];//转成十进制放入packet
				k++;
			}


			printf("src mac making !!!\n");
			for (i = 0; i < 64; i++)
			{
				printf(" %02x", packet[i]);
				if ((i + 1) % 16 == 0)
				{
					printf("\n");
				}
			}
			printf("\n\n");

			char srcIp[100] = { 0 };
			char desIp[100] = { 0 };
			strcpy(srcIp, local_ip);
			strcpy(desIp, recSrcIp);

			//源IP地址
			k = 0;
			int j = 0;
			temp[2] = 0;  //指向每个字节初始位置
			for (i = 0; i < 4; i++)
			{
				temp[0] = 0;
				temp[1] = 0;
				for (j = 0; j < 4; j++)
				{
					if (srcIp[j + temp[2]] >= '0'&&srcIp[j + temp[2]] <= '9')
					{
						temp[0] = (int)srcIp[j + temp[2]] - 48;//字符1转int型数据1
						temp[1] = temp[1] * 10 + temp[0];//字符192转换成int数据192，累乘10
						//printf("%d %d\n",temp[0],temp[1]);
					}
					else
					{
						//当遇到点时j自加1目的是让temp[2]+j指向下一字节的第一位
						j++;
						break;
					}
				}
				packet[28 + 4 + k] = temp[1];
				k++;
				temp[2] += j;
			}

			printf("src ip making !!!\n");
			for (i = 0; i < 64; i++)
			{
				printf(" %02x", packet[i]);
				if ((i + 1) % 16 == 0)
				{
					printf("\n");
				}
			}
			printf("\n\n");

			//目标IP地址
			k = 0;
			temp[2] = 0;
			for (i = 0; i < 4; i++)
			{
				temp[0] = 0;
				temp[1] = 0;
				for (j = 0; j < 4; j++)
				{
					if (desIp[j + temp[2]] >= '0'&&desIp[j + temp[2]] <= '9')
					{
						temp[0] = (int)desIp[j + temp[2]] - 48;
						temp[1] = temp[1] * 10 + temp[0];
						//printf("%d %d\n",temp[0],temp[1]);
					}
					else
					{
						j++;
						break;
					}
				}
				packet[38 + 4 + k] = temp[1];
				k++;
				temp[2] += j;
			}

			printf("des ip making !!!\n");
			for (i = 0; i < 64; i++)
			{
				printf(" %02x", packet[i]);
				if ((i + 1) % 16 == 0)
				{
					printf("\n");
				}
			}
			printf("\n\n");

			//ARP首部
			packet[12] = 0x81;//802.1Q协议
			packet[13] = 0x00;
			packet[14] = packet_content[14];
			packet[15] = packet_content[15];//vlanId,会需要从收到的包中解析出来.

			packet[16] = 0x08;//12、13位为帧类型
			packet[17] = 0x06;
			packet[18] = 0x00;//14、15位为硬件类型
			packet[19] = 0x01;
			packet[20] = 0x08;//16、17位为协议类型
			packet[21] = 0x00;
			packet[22] = 0x06;//硬件地址长度
			packet[23] = 0x04;//协议地址长度
			packet[24] = 0x00;//op
			packet[25] = 0x02;//op(1为请求2为应答)


			/* 填充发送包的剩余部分 */
			for (i = 0; i < 18; i++)
			{
				packet[42 + 4 + i] = 0;
			}

			////这里后四个字节本应该是校验位,这里就不算了，写个日期纪念一下
			packet[59] = 0x20;
			packet[60] = 0x21;
			packet[61] = 0x11;
			packet[62] = 0x06;
			/* 发送包 */

			printf("send packet!!!\n");
			for (i = 0; i <64; i++)
			{
				printf(" %02x", packet[i]);
				if ((i + 1) % 16 == 0)
				{
					printf("\n");
				}
			}
			printf("\n\n");

			pcap_sendpacket(((pcapCallBakArg*)arg)->pcap_handle, packet, 64);
			printf(" send Success!\n");
		}
	}
	else 
	{
		printf("ipv6 is used\n");
	}

	printf("------------------done-------------------\n");
	printf("\n\n");
}

int main(int argc, char *argv[])
{
	pcapCallBakArg pcapArg;
	memset(&pcapArg, 0, sizeof(pcapCallBakArg));

	char *dev;
	char  errbuf[1024];

	//确定嗅探设备，确定网络接口
	dev = argv[1];//传参作为嗅探设备
	//dev = pcap_lookupdev(errbuf);
	if (dev == NULL) 
	{
		printf("%s\n", errbuf);
		return 0;
	}
	printf("Device: %s\n", dev);

	strcpy(pcapArg.devName, dev);
	//打开嗅探设备，准备嗅探，打开网络接口
	//pcap_t *pcap_handle = pcap_open_live(dev, 65535, 1, 0, errbuf);
	pcap_t * pcap_handle = pcap_open_live(dev, 65535, 1, 0, errbuf);

	if (pcap_handle == NULL) 
	{
		printf("%s\n", errbuf);
		return 0;
	}

	//获取网络号ip和掩码
	struct in_addr addr;
	bpf_u_int32 ipaddress, ipmask;
	char *dev_ip, *dev_mask;

	if (pcap_lookupnet(dev, &ipaddress, &ipmask, errbuf) == -1) {
		printf("%s\n", errbuf);
		return 0;
	}

	//输出ip
	addr.s_addr = ipaddress;
	dev_ip = inet_ntoa(addr);
	printf("ip address : %s\n", dev_ip);

	//输出掩码
	addr.s_addr = ipmask;
	dev_mask = inet_ntoa(addr);
	printf("netmask : %s\n", dev_mask);


	//int pcap_loop(pcap_t *p, int cnt, pcap_handler callback, u_char *user);
	//循环捕获网络数据包，直到遇到错误或者满足退出条件，每次捕获一个数据包就会调用callback指定的回调函数，
	//所以，可以在回调函数中进行数据包的处理操作，返回值：成功返回0，失败返回负数
	//p：pcap_open_live()返回的pcap_t类型的指针
	//cnt：指定捕获数据包的个数，一旦抓到cnt个数据包，pcap_loop立即返回，如果是 - 1，就会一直捕获直到出错
	//callback : 回调函数，名字任意，可在其中处理数据包
	//user：向回调函数中传递的参数

	struct bpf_program filter;
	//过滤的只抓arp包
	if (pcap_compile(pcap_handle, &filter, "ether proto \\arp", 1, 0) < 0) {
		printf("error\n");
		return 0;
	}
	if (pcap_setfilter(pcap_handle, &filter) < 0) 
	{
		printf("error\n");
		return 0;
	}


	printf("---------packet--------\n");

	int id = 0;


	pcap_dumper_t* dumpfp = pcap_dump_open(pcap_handle, "./save1.pcap");

	pcapArg.fileHandle = dumpfp;
	pcapArg.pcap_handle = pcap_handle;


	if (pcap_loop(pcap_handle, -1, pcap_callback, (unsigned char*)&pcapArg) < 0)
	{
		printf("error\n");
		return 0;
	}

	pcap_dump_close(dumpfp);
	pcap_close(pcap_handle);
	return 0;
}